// ChunkView.cpp : implementation file
//

#include "stdafx.h"
#include "U7FileTool.h"
#include "ChunkDoc.h"
#include "ChunkView.h"

#include "Shape.h"

const int MAX_COLS = 64;
const int MAX_ROWS = 3072/MAX_COLS;

// CChunkView

IMPLEMENT_DYNCREATE(CChunkView, CScrollView)

CChunkView::CChunkView()
{
	m_pGraphic = NULL;
}

CChunkView::~CChunkView()
{
	if ( m_pGraphic )
	{
		DeleteGraphic(m_pGraphic);
		m_pGraphic = NULL;
	}
}


BEGIN_MESSAGE_MAP(CChunkView, CScrollView)
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
END_MESSAGE_MAP()

void DrawChunk( PGRAPHIC pGraphic, PSHAPEID shapeID, const char* shapeFile, int ox, int oy )
{
	for ( int i = 0; i < CHUNK_LENGTH; i++ )
	{
		int x = (i%CHUNK_WIDTH) * TILE_WIDTH;
		int y = (i/CHUNK_HEIGHT) * TILE_HEIGHT;
		DrawShape( pGraphic, shapeFile, shapeID, ox + x, oy + y );
		shapeID++;
	}

}

void CChunkView::PrepareGraphic( int ox, int oy, int cx, int cy )
{
	if ( m_pGraphic )
	{
		if ( m_pGraphic->width != cx || m_pGraphic->height != cy )
		{
			DeleteGraphic(m_pGraphic);
			m_pGraphic = NULL;
		}
	}

	if ( !m_pGraphic )
		m_pGraphic = CreateGraphic( cx, cy, 8, ((const BITMAPINFO *)theApp.m_bitmapInfo)->bmiColors );

	ASSERT(m_pGraphic);

	const int chunkCX = CHUNK_WIDTH * TILE_WIDTH;
	const int chunkCY = CHUNK_HEIGHT * TILE_HEIGHT;

	int offsetX = (ox%chunkCX);
	int offsetY = (oy%chunkCY);
	ox -= offsetX;
	oy -= offsetY;

	int numChunkX = (cx + offsetX + chunkCX - 1) / chunkCX;
	int numChunkY = (cy + offsetY + chunkCY - 1) / chunkCY;

	CChunkDoc* pDoc = (CChunkDoc*)GetDocument();
	int count = pDoc->GetChunkCount();

	int startChkX = ox / chunkCX;
	int startChkY = oy / chunkCY;

	for ( int chy = 0; chy < numChunkY; chy++ )
	{
		for ( int chx = 0; chx < numChunkX; chx++ )
		{
			int chunkIndex = (chx+startChkX) + (chy+startChkY) * MAX_COLS;
			PSHAPEID pShapeID = pDoc->GetChunk(chunkIndex);

			int x = chx * chunkCX + TILE_WIDTH -1 - offsetX;
			int y = chy * chunkCY + TILE_HEIGHT - 1 - offsetY;
			DrawChunk( m_pGraphic, pShapeID, (const char*)theApp.m_pShapeFile, x, y );
		}
	}
}

// CChunkView drawing

void CChunkView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSize sizeTotal;
	// TODO: calculate the total size of this view
	// 64 * 48 = 3072
	sizeTotal.cx = MAX_COLS * CHUNK_WIDTH * TILE_WIDTH;
	sizeTotal.cy = MAX_ROWS * CHUNK_WIDTH * TILE_HEIGHT;
	SetScrollSizes(MM_TEXT, sizeTotal);

	CRect rcClient;
	GetClientRect(&rcClient);

	CPoint ptOrg = GetScrollPosition();

	PrepareGraphic( ptOrg.x, ptOrg.y, rcClient.Width(), rcClient.Height() );	
}

void CChunkView::OnDraw(CDC* pDC)
{
	CChunkDoc* pDoc = (CChunkDoc*)GetDocument();
	// TODO: add draw code here
	CPoint ptOrg = GetScrollPosition();
	CRect rcClient;
	GetClientRect(&rcClient);

	PrepareGraphic( ptOrg.x, ptOrg.y, rcClient.Width(), rcClient.Height() );

	if ( m_pGraphic )
	{
		::StretchDIBits(
			pDC->GetSafeHdc(),
			ptOrg.x, ptOrg.y, m_pGraphic->width, m_pGraphic->height,
			0, 0, m_pGraphic->width, m_pGraphic->height,
			m_pGraphic->pBits,
			&m_pGraphic->bmInfo,
			DIB_RGB_COLORS,
			SRCCOPY );
	}

	int xpos = (ptOrg.x + 127) & (~127);
	int ypos = (ptOrg.y + 127) & (~127);
	CString str;
	str.Format( _T("%d"), xpos/128 + (ypos/128) * 64 );
	pDC->SelectStockObject(WHITE_PEN);
	pDC->SelectStockObject(BLACK_BRUSH);
	pDC->TextOut( xpos, ypos, str );
}


// CChunkView diagnostics

#ifdef _DEBUG
void CChunkView::AssertValid() const
{
	CScrollView::AssertValid();
}

#ifndef _WIN32_WCE
void CChunkView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}
#endif
#endif //_DEBUG


// CChunkView message handlers


void CChunkView::OnSize(UINT nType, int cx, int cy)
{
	CScrollView::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
}


BOOL CChunkView::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
	//return CScrollView::OnEraseBkgnd(pDC);
	return TRUE;
}


void CChunkView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default
	CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}


void CChunkView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default
	CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);	
}
